#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
异步数据同步示例
展示如何使用 AsyncSyncHandler 进行高性能数据同步

关键特性:
1. 异步 I/O 操作，提高数据库并发性能
2. 连接池管理，避免频繁创建/销毁连接
3. 事务一致性保证，确保数据完整性
4. 并发控制，防止资源过载
5. 支持 Polars 进行高性能数据处理
"""

import asyncio
import sys
import os
from datetime import datetime, timedelta
from loguru import logger

# 添加项目根目录到路径
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from src.async_sync_handler import AsyncSyncHandler, async_sync_task, sync_task_with_async


async def async_sync_example():
    """
    异步同步示例 - 推荐方式
    """
    logger.info("=== 异步数据同步示例 ===")
    
    # 设置同步参数
    start_date = '2024-01-01'
    end_date = '2024-01-31'
    batch_size = 500  # 批处理大小
    max_concurrent_batches = 3  # 最大并发批次
    max_connections = 10  # 最大连接数
    
    try:
        # 方式1: 使用上下文管理器（推荐）
        async with AsyncSyncHandler(max_connections=max_connections) as handler:
            result = await handler.sync_task_async(
                start_date=start_date,
                end_date=end_date,
                batch_size=batch_size,
                max_concurrent_batches=max_concurrent_batches
            )
            
            logger.info(f"同步结果: {result}")
            logger.info(f"成功处理: {result['success_count']} 条")
            logger.info(f"处理失败: {result['error_count']} 条")
            logger.info(f"总耗时: {result['duration']:.2f} 秒")
            
            if result['error_details']:
                logger.warning(f"错误详情: {result['error_details'][:5]}...")  # 只显示前5个错误
    
    except Exception as e:
        logger.exception(f"异步同步失败: {e}")


async def async_sync_with_custom_params():
    """
    自定义参数的异步同步示例
    """
    logger.info("=== 自定义参数异步同步示例 ===")
    
    # 获取上个月的日期范围
    today = datetime.today()
    first_day_this_month = today.replace(day=1)
    last_month_end = first_day_this_month - timedelta(days=1)
    last_month_start = last_month_end.replace(day=1)
    
    start_date = last_month_start.strftime('%Y-%m-%d')
    end_date = first_day_this_month.strftime('%Y-%m-%d')
    
    logger.info(f"同步日期范围: {start_date} 到 {end_date}")
    
    # 使用便捷函数
    result = await async_sync_task(
        start_date=start_date,
        end_date=end_date,
        batch_size=1000,  # 更大的批次
        max_concurrent_batches=5,  # 更高的并发
        max_connections=15  # 更多连接
    )
    
    logger.info(f"自定义参数同步完成: {result}")


def sync_example_in_sync_context():
    """
    在同步环境中使用异步处理器的示例
    适用于需要在现有同步代码中集成异步功能的场景
    """
    logger.info("=== 同步环境中的异步处理示例 ===")
    
    # 使用同步包装器
    result = sync_task_with_async(
        start_date='2024-01-01',
        end_date='2024-01-31',
        batch_size=800,
        max_concurrent_batches=4,
        max_connections=12
    )
    
    logger.info(f"同步环境异步处理结果: {result}")
    return result


async def performance_comparison():
    """
    性能对比示例
    """
    logger.info("=== 性能对比示例 ===")
    
    # 小批次高并发 vs 大批次低并发
    configs = [
        {
            'name': '小批次高并发',
            'batch_size': 200,
            'max_concurrent_batches': 8,
            'max_connections': 20
        },
        {
            'name': '大批次低并发',
            'batch_size': 2000,
            'max_concurrent_batches': 2,
            'max_connections': 8
        }
    ]
    
    for config in configs:
        logger.info(f"测试配置: {config['name']}")
        
        start_time = asyncio.get_event_loop().time()
        
        result = await async_sync_task(
            start_date='2024-01-01',
            end_date='2024-01-02',  # 小范围测试
            batch_size=config['batch_size'],
            max_concurrent_batches=config['max_concurrent_batches'],
            max_connections=config['max_connections']
        )
        
        end_time = asyncio.get_event_loop().time()
        
        logger.info(f"{config['name']} 结果:")
        logger.info(f"  - 处理记录: {result['success_count']}")
        logger.info(f"  - 总耗时: {end_time - start_time:.2f} 秒")
        logger.info(f"  - 平均速度: {result['success_count']/(end_time - start_time):.2f} 记录/秒")


async def concurrent_multiple_tasks():
    """
    并发执行多个同步任务的示例
    """
    logger.info("=== 并发多任务示例 ===")
    
    # 定义多个时间段的同步任务
    date_ranges = [
        ('2024-01-01', '2024-01-10'),
        ('2024-01-11', '2024-01-20'),
        ('2024-01-21', '2024-01-31')
    ]
    
    # 创建任务列表
    tasks = []
    for i, (start_date, end_date) in enumerate(date_ranges):
        task = async_sync_task(
            start_date=start_date,
            end_date=end_date,
            batch_size=500,
            max_concurrent_batches=2,  # 降低单任务并发，因为有多个任务
            max_connections=8
        )
        tasks.append(task)
    
    # 并发执行所有任务
    results = await asyncio.gather(*tasks, return_exceptions=True)
    
    # 统计总结果
    total_success = 0
    total_errors = 0
    total_duration = 0
    
    for i, result in enumerate(results):
        if isinstance(result, Exception):
            logger.error(f"任务 {i+1} 执行失败: {result}")
        else:
            total_success += result['success_count']
            total_errors += result['error_count']
            total_duration = max(total_duration, result['duration'])
            logger.info(f"任务 {i+1} ({date_ranges[i]}) 完成: {result['success_count']} 成功")
    
    logger.info(f"所有任务完成:")
    logger.info(f"  - 总成功: {total_success}")
    logger.info(f"  - 总失败: {total_errors}")
    logger.info(f"  - 最长耗时: {total_duration:.2f} 秒")


def main():
    """
    主函数 - 演示各种使用方式
    """
    logger.info("开始异步数据同步示例演示")
    
    # 配置日志
    logger.remove()
    logger.add(
        sys.stdout,
        format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level: <8}</level> | {message}",
        level="INFO"
    )
    
    try:
        # 1. 基础异步同步示例
        asyncio.run(async_sync_example())
        
        print("\n" + "="*50 + "\n")
        
        # 2. 自定义参数示例
        asyncio.run(async_sync_with_custom_params())
        
        print("\n" + "="*50 + "\n")
        
        # 3. 同步环境示例
        sync_example_in_sync_context()
        
        print("\n" + "="*50 + "\n")
        
        # 4. 性能对比示例
        asyncio.run(performance_comparison())
        
        print("\n" + "="*50 + "\n")
        
        # 5. 并发多任务示例
        asyncio.run(concurrent_multiple_tasks())
        
    except KeyboardInterrupt:
        logger.info("用户中断执行")
    except Exception as e:
        logger.exception(f"示例执行失败: {e}")
    
    logger.info("异步数据同步示例演示完成")


if __name__ == "__main__":
    main()


"""
关于用户问题的详细解答:

1. 多线程与异步是否冲突？
   答：不冲突，但有区别：
   - 异步(async/await): 单线程内的协程并发，适合I/O密集型任务（如数据库操作）
   - 多线程: 真正的并行执行，适合CPU密集型任务
   - 可以结合使用: 异步处理I/O + 线程池处理CPU密集任务
   
   本示例使用异步是因为数据库操作是I/O密集型，异步能提供更好的性能和资源利用率。

2. 事务完整性保障：
   - 使用连接池的事务管理
   - 每个批次作为一个事务单元
   - 失败时自动回滚，保证数据一致性
   - 通过 async with conn.cursor() 确保连接正确释放

3. Polars官网：
   - 官网: https://pola.rs/
   - GitHub: https://github.com/pola-rs/polars
   - 文档: https://pola-rs.github.io/polars/
   
   Polars是用Rust编写的高性能DataFrame库，比pandas快很多倍，
   特别适合大数据处理和ETL场景。

性能优化建议：
1. 调整batch_size和max_concurrent_batches平衡内存和性能
2. 根据数据库连接数限制调整max_connections
3. 使用Polars替代pandas进行数据处理
4. 监控数据库连接池使用情况
5. 根据网络延迟调整超时设置
"""